package com.ptszyxx.popose.module.main.user;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProviders;

import com.ptszyxx.popose.BR;
import com.ptszyxx.popose.R;
import com.ptszyxx.popose.common.voice.RecordManager;
import com.ptszyxx.popose.common.voice.RecordStateListener;
import com.ptszyxx.popose.common.voice.VoicePlayer;
import com.ptszyxx.popose.databinding.FragmentUserEditVoiceBinding;
import com.ptszyxx.popose.module.main.user.vm.UserEditVoiceVM;
import com.ysg.base.BaseFragment;
import com.ysg.http.data.AppViewModelFactory;
import com.ysg.utils.YCollectionUtil;
import com.ysg.utils.YImageUtil;
import com.ysg.utils.YPermissionUtil;
import com.ysg.utils.YToastUtil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;

public class UserEditVoiceFragment extends BaseFragment<FragmentUserEditVoiceBinding, UserEditVoiceVM> {

    @Override
    public int initContentView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return R.layout.fragment_user_edit_voice;
    }

    @Override
    public int initVariableId() {
        return BR.viewModel;
    }

    @Override
    public UserEditVoiceVM initViewModel() {
        AppViewModelFactory factory = AppViewModelFactory.getInstance(getActivity().getApplication());
        return ViewModelProviders.of(this, factory).get(UserEditVoiceVM.class);
    }

    @Override
    public void initView() {
        super.initView();
    }

    @Override
    public void initData() {
        super.initData();
        viewModel.requestVoiceRandom();
        initRecordManager();
    }

    @Override
    public void initViewObservable() {
        super.initViewObservable();
        viewModel.uc.onVoiceSignEvent.observe(this, o -> setVoiceRandomUI((String) o));
        viewModel.uc.onStartEvent.observe(this, o -> onStartRecode());
        viewModel.uc.onRestartEvent.observe(this, o -> onRestartRecode());
        viewModel.uc.onListenerEvent.observe(this, o -> onListenerRecode());
        viewModel.uc.onSubmitEvent.observe(this, o -> onSubmitRecode());
    }

    private void onSubmitRecode() {
        status = PREVIEW;
        showPager();
        if (TextUtils.isEmpty(myVoice)) {
            linkVoice();
        }

        if (myVoice != null) {
            File file = new File(myVoice);
            if (file != null) {
                String[] split = binding.chronometer.getText().toString().split(":");
                if (YCollectionUtil.isNotEmpty(split) && split.length >= 2){
                    String seconds = Integer.valueOf(split[0]) * 60 + split[1] + "";
                    viewModel.requestUploadAudio(file, seconds);
                }
            }
        }
    }

    private void onListenerRecode() {
        if (status == PAUSE){
            showPager();
            if (TextUtils.isEmpty(myVoice)) {
                linkVoice();
            }
            playVoice();
        }
    }

    private void onRestartRecode() {
        status = STOP;
        showPager();
        cancel();
    }


    private static final int STOP = 0;   // 停止
    private static final int RECORD = 1; // 正在录制
    private static final int PAUSE = 2;  // 暂停
    private static final int PREVIEW = 3;// 试听
    private static final int PLAY = 4; // 播放状态
    private RecordManager recordManager; // 音频录制管理类
    private int status = STOP; //当前的状态   0表示停止录制  1表示正在录制  2表示暂停录制
    private int time = 0; // 最终录制的时间
    private int remainingTime = 60;// 剩余的时间
    private int minTime = 0; // 每次录音的最短的时间
    private List<String> voices;// 所有间断产生的音频文件的路径
    private String myVoice; // 最终合并的文件路径
    private boolean isCancel = false; // 标记
    private long statrcurent;
    private long stopcurent;
    private VoicePlayer voicePlayer; // 音频播放器
    private int voicePlayStatus = STOP; // 音频的播放状态


    private void initRecordManager() {
        recordManager = RecordManager.getInstance();
        recordManager.setVoiceVolumeListener(new RecordStateListener() {
            @Override
            public void onRecordStarting() {
            }

            @Override
            public void onRecordStart() {
                statrcurent = System.currentTimeMillis();
                new RecordTime().start();
            }

            @Override
            public void onRecordFinish(String file) {
                stopcurent = System.currentTimeMillis();
                File voiceFile = new File(file);
                if (isCancel && voiceFile.exists()) {
                    voiceFile.delete();
                    isCancel = false;
                    return;
                }
                if (voiceFile.exists()) {
                    voices.add(file);
                }
            }

            @Override
            public void onRecordCancel() {

            }

            @Override
            public void onRecordVolumeChange(int v) {

            }

            @Override
            public void onRecordTimeChange(int seconds) {

            }

            @Override
            public void onRecordError() {

            }

            @Override
            public void onRecordTooShoot() {

            }
        });
        voices = new ArrayList<>(); // 储存录制的所有音频文件的路径
    }

    private void setVoiceRandomUI(String s) {
        binding.tvContent.setText(s);
    }

    private void onStartRecode() {
        YPermissionUtil.requestAudio(getActivity(), "申请录音权限：用于录制个人语音签名", new YPermissionUtil.OnPermissionListener() {
            @Override
            public void onSuccess() {
                if (status == STOP) // 当前为停止状态，点击后进入正在录制界面
                {
                    Log.i("语音录制", "=====STOP======" + status);
                    status = RECORD;
                    start();
                    showPager();
                } else if (status == RECORD) // 当前为正在录制界面，点击后进入暂停录制界面
                {

                    Log.i("语音录制", "=====RECORD======" + status);
                    status = PAUSE;
                    showPager();
                } else if (status == PAUSE)//当前为暂停录制界面，点击后恢复正在录制界面
                {
                    status = RECORD;
                    start();
                    showPager();
                    linkVoice();
                } else if (status == PREVIEW) // 试听状态就直接播放音频
                {
                    Log.i("语音录制", "=====PREVIEW======" + status);
                    if (voicePlayStatus == STOP) {
                        playVoice();
                    } else if (voicePlayStatus == PLAY) {
                        voicePlayer.stop();
                        voicePlayStatus = STOP;
                    }
                }
            }

            @Override
            public void onError() {
                YToastUtil.showShort("您拒绝了录音权限");
            }
        });
    }

    public void start() {
        binding.chronometer.setBase(SystemClock.elapsedRealtime());
        binding.chronometer.start();
        recordManager.startRecord();
    }

    public void stop() {
        binding.chronometer.stop();
        recordManager.stop();
    }

    public void cancel() {
        if (voicePlayer != null) {
            if (voicePlayStatus == PLAY) {
                voicePlayer.stop();
            }
        }
        myVoice = "";
        if (voices.isEmpty()) {
            return;
        }
        for (int i = 0; i < voices.size(); i++) {
            File file = new File(voices.get(i));
            if (file.exists()) {
                file.delete();
            }
        }
        voices.clear(); // 清除路径
    }

    private void showPager() {
        switch (status) {
            case STOP: // 停止录制
            {
                binding.llEnd.setVisibility(View.GONE);
                binding.llGoing.setVisibility(View.VISIBLE);
                binding.ivStart.setImageResource(R.mipmap.ic_voice_start_record);
                binding.tvStart.setVisibility(View.VISIBLE);
                binding.chronometer.setVisibility(View.GONE);
            }
            break;

            case RECORD: // 正在录制
            {
                binding.tvStart.setVisibility(View.GONE);
                binding.chronometer.setVisibility(View.VISIBLE);
                binding.llGoing.setVisibility(View.VISIBLE);
                binding.ivStart.setImageResource(R.mipmap.ic_voice_record_stop);
                YImageUtil.showGif(binding.ivStart, R.mipmap.ic_voice_gif);
                binding.llEnd.setVisibility(View.GONE);
            }
            break;
            case PAUSE:// 暂停录制
            case PREVIEW:// 试听
            {
                binding.llEnd.setVisibility(View.VISIBLE);
                binding.llGoing.setVisibility(View.GONE);
                binding.tvListener.setText(getResources().getString(R.string.user_edit_voice_audition) + "  " + binding.chronometer.getText().toString());
            }
            break;
        }
    }

    // 播放录音
    private void playVoice() {
        voicePlayer = null;
        voicePlayer = new VoicePlayer();
        voicePlayer.play(myVoice);
        voicePlayStatus = PLAY;
        voicePlayer.setOnFinishPlayListener(new VoicePlayer.OnFinishPlayListener() {
            @Override
            public void onFinishPlay() {
                voicePlayStatus = STOP;
            }
        });
    }

    private class RecordTime extends Thread {
        public void run() {
            minTime = 0;
            while (time < 60 && time >= 0 && status == RECORD) {
                time++;
                minTime++;
                remainingTime--;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (remainingTime <= 0) {
                    getActivity().finish();
                }
                Message msg = new Message();
                msg.what = RECORD;
                handler.sendMessage(msg);
            }

            if (minTime < 2) {
                Message msg = new Message();
                msg.what = PAUSE;
                handler.sendMessage(msg);
            } else {
                if (status != PAUSE) {
                    recordManager.stop();
                }
                Message msg = new Message();
                msg.what = STOP;

                handler.sendMessage(msg);
            }
        }
    }

    /**
     * 连接各个录音片段
     */
    public void linkVoice() {
        Log.i("语音录制", "=====linkVoice======" + voices.toString());
        if (voices.size() == 0)
            return;
        String path;
        int end = voices.get(0).lastIndexOf("/");
        path = voices.get(0).substring(0, end);
        myVoice = path + "/" + System.currentTimeMillis() + "_voice.amr";
        uniteAMRFile(voices, myVoice);
        //合并成功后就删除每个语音片段文件
        for (int i = 0; i < voices.size(); i++) {
            File file = new File(voices.get(i));
            if (file.exists()) {
                file.delete();
            }
        }
    }

    /**
     * 需求:将两个amr格式音频文件合并为1个
     * 注意:amr格式的头文件为6个字节的长度
     *
     * @param partsPaths     各部分路径
     * @param unitedFilePath 合并后路径
     */
    public void uniteAMRFile(List<String> partsPaths, String unitedFilePath) {
        try {
            File unitedFile = new File(unitedFilePath);
            FileOutputStream fos = new FileOutputStream(unitedFile);
            RandomAccessFile ra = null;
            for (int i = 0; i < partsPaths.size(); i++) {
                ra = new RandomAccessFile(partsPaths.get(i), "r");
                if (i != 0) {
                    ra.seek(6);
                }
                byte[] buffer = new byte[1024 * 8];
                int len = 0;
                while ((len = ra.read(buffer)) != -1) {
                    fos.write(buffer, 0, len);
                }
            }
            ra.close();
            fos.close();
        } catch (Exception e) {
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (null != voicePlayer) {
            voicePlayer.stop();
        }
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.i("语音录制", "-----------" + msg.what);
            if (msg.what == RECORD) {
            } else if (msg.what == STOP) {
                if (status == PAUSE) {
                    Log.i("语音录制", "-----ss1------" + status);
                    showPager();
                    linkVoice();
                    stop();
                } else {
                    Log.i("语音录制", "-----ss2------" + status);
                    status = STOP;
                    showPager();
                    linkVoice();
                }
            } else if (msg.what == PAUSE) {
                Log.i("语音录制", "-----ss0------" + status);
                remainingTime++; // 录音保存不成功，把减去的时间恢复
                showPager();
                linkVoice();
                isCancel = true;
                stop();
            }
        }
    };
}
